Display images in Adaptive Cards
Table of contents:
Images always enricher Adaptive Cards designs. However in Microsoft Teams max. message payload is just 25KB and that includes also the size of card’s JSON. Therefore it is very often not possible to display even the smallest image inline. What other options we have?
Images in Adaptive Cards
Basically images are displayed in Adaptive Cards using “Image” element. In its properties you need to type the URL to an image:
Important! Image’s URL must start with https and be a direct link to a file itself (ending up with jpg, png, tiff, etc…).
Ok, so what are the options to display images in Adaptive Cards? Actually two:
- Via an absolute hyperlink to the file itself
- Via data uri – base64 encoded file contents
The first approach I already explained above. It’s quite simple. The second one requires to take file contents and encode them using base64. This can be done upfront, manually, using online services eg. Base64 Image Encoder. Or, using expression dataUri(file content)
in Power Automate:
What is returned, looks like the following string: data:image/jpeg;base64,/9j/4AAJRgABAQ….QP//Z
. The longer that string is, the bigger the file is. Finally, that string (or expression in Power Automate) must be put as a value inside Url property of the Image element in Adaptive Card design.
Important! Microsoft Teams message payload can have a size of max. 25KB as of today – that includes the JSON. So if you encode image into base64 it’s easy to realize, that having so many characters will push the payload to easily exceed that limit. 25KB is 25 000 bytes, while one character is encoded as 1 to 4 bytes. Just an example, $ needs one byte, whereas € needs 3 bytes.
Where to store images?
Basically, the image that is going to be displayed must be available anonymously. This is because, Adaptive Card in MS Teams is displayed by a Teams Bot, not the authenticated user’s account, therefore it is not having the same access permissions as the user who displays the card.
Knowing that, it is not possible to store and display images from SharePoint using absolute path. You can try, by first converting images to data uri, but remember the payload size 🙂
What other places can be used then?
- Anonymous FTP server
- Some online image services like Imgur
- WordPress
- Azure Blob Storage
- others, allowing to access contents without authentication
OneDrive cannot be used as a storage to host images, since even when we select to share an image with anyone:
The generated link is still not a valid, absolute link to a file itself, but to a page that displays the image, so when you put it as a Url property, it won’t display the image:
How to store images securely, but still display them in Adaptive Cards?
In such case you need to look for services that allow to secure contents with connection string/ SAS (shared access signature) that can be added to absolute URL as url parameters. My favorite is Azure Blob Storage. Let me show you how.
- Sign in to Azure portal and create new Storage account:
- Once account is provisioned, open it and:
- Navigate to Containers
- Click to create new container
- Provide its name and set its access to Private
- Now upload image you would like to display in Adaptive Card:
- Click the Upoad link
- Choose a file you want to upload and select all properties as per your choice
- Finally after upload navigate to Shared access tokens page
- And finally generate the SAS token, that you can append to the absolute image link to make it available for display.
- Define type of permissions – for this scenario only Read is sufficient
- Define expiration dates – when token will expire and asset will become inaccessible again
- Select HTTPS only, since that is what Adaptive Cards support
- Click to Generate SAS token and URL
- Copy the SAS token
Now you’re ready to navigate back to container contents, open file details, copy its path and append with SAS token:
Then paste such URL back to Url property of Image element in Adaptive Card and voilla! There it is:
I hope you will find this short tutorial useful. Please write down in comments what other providers you use to securely host images and access them using SAS/ access tokens.
Porchetta
Great info. You may want to mention that SVG images are not supported in TEAMS + OUTLOOK. An SVG image works fine in the Adaptive Card editor only.
Tomasz Poszytek
Thanks for the highlight. It works as well in custom implementations of Adaptive Cards SDK.
Jake Mannion
Clever method for handling the image storage… I wonder if this can be adapted for Actionable Messages in Outlook, too?
After I make this comment, I will go and look and see if your blog has a subscribe option. 🙂 Good work Tomasz.
Wes
I have tried direct anonymous image URL path in an Azure web site, as well the Azure Blob storage method you describe above. I experience the same dilemma in either case – the images do not display in Outlook adaptive cards when the messages are first opened. Once you close the message and go back in, the image appears. I have duplicated this behavior using multiple images, and also tried to outsmart caching by appending query string variables on the end of the image URL. No difference. However, if I use the same URLs in the card *background* image instead, the image seems to always display. I don’t like using this method, however, as the image is easily skewed on different devices or screen sizes. This started happening about a year ago out of the blue. I have never found a workaround to this day.
Tomasz Poszytek
I have no solution for that either. Sorry.